﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// A descriptor for a single instance of a tile.
/// </summary>
public class TileDescriptor {

    public bool NorthWall = false;
    public bool EastWall = false;
    public bool SouthWall = false;
    public bool WestWall = false;

    public bool NorthwestCorner = false;
    public bool SouthwestCorner = false;
    public bool NortheastCorner = false;
    public bool SoutheastCorner = false;

    public TileDescriptor()
    {
    }

    /// <summary>
    /// Creates a new tile from an 8-bit integer index.
    /// </summary>
    /// <param name="intForm">Okay, if you really want to know, the order from most significant digit to least is: South wall, west wall, north wall, east wall, southwest corner, northwest corner, northeast corner, southeast corner.</param>
    public TileDescriptor(int intForm)
    {
        SouthWall = (intForm & 128) > 0;
        WestWall = (intForm & 64) > 0;
        NorthWall = (intForm & 32) > 0;
        EastWall = (intForm & 16) > 0;

        SouthwestCorner = (intForm & 8) > 0;
        NorthwestCorner = (intForm & 4) > 0;
        NortheastCorner = (intForm & 2) > 0;
        SoutheastCorner = (intForm & 1) > 0;
    }

    /// <summary>
    /// Parses any string that has at least 8 binary digits and creates a tile from it. For order of the bits, see the int constructor. For sanity, use the same format as ToString().
    /// </summary>
    /// <param name="stringForm"></param>
    public TileDescriptor(string stringForm)
    {
        List<int> digits = new List<int>();
        for (int index = 0; index < stringForm.Length && digits.Count < 8; index++)
            if (stringForm[index] == '0' || stringForm[index] == '1')
                digits.Add(int.Parse(stringForm[index].ToString()));

        SouthWall = digits.Count > 0 && digits[0] == 1;
        WestWall = digits.Count > 1 && digits[1] == 1;
        NorthWall = digits.Count > 2 && digits[2] == 1;
        EastWall = digits.Count > 3 && digits[3] == 1;

        SouthwestCorner = digits.Count > 4 && digits[4] == 1;
        NorthwestCorner = digits.Count > 5 && digits[5] == 1;
        NortheastCorner = digits.Count > 6 && digits[6] == 1;
        SoutheastCorner = digits.Count > 7 && digits[7] == 1;

    }

    /// <summary>
    /// Returns the string form of the description in a friendly prefab-name format.
    /// </summary>
    /// <returns></returns>
    public override string ToString()
    {
        return string.Format("floor_w{0}{1}{2}{3}_c{4}{5}{6}{7}", SouthWall ? 1 : 0, WestWall ? 1 : 0, NorthWall ? 1 : 0, EastWall ? 1 : 0, SouthwestCorner ? 1 : 0, NorthwestCorner ? 1 : 0, NortheastCorner ? 1 : 0, SoutheastCorner ? 1 : 0);
    }

    /// <summary>
    /// "What on earth?"
    /// Well, since we have 8 binary pieces of information, we can represent a tile as a byte.
    /// We'll use ints since we can afford the memory and we won't lose performance to conversions.
    /// </summary>
    /// <returns>An 8-bit integer value encoding the walls and corners of the tile.</returns>
    public int ToInt()
    {
        return (SouthWall ? 128 : 0) +
            (WestWall ? 64 : 0) +
            (NorthWall ? 32 : 0) +
            (EastWall ? 16 : 0) +
            (SouthwestCorner ? 8 : 0) +
            (NorthwestCorner ? 4 : 0) +
            (NortheastCorner ? 2 : 0) +
            (SoutheastCorner ? 1 : 0);
    }

}
